package com.zhht.htzx.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.net.Uri;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.camera.core.ImageProxy;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.EnumMap;
import java.util.Map;

/**
 * 二维码扫描工具类
 */
public class QRCodeScannerUtils {
    private static final String TAG = "QRCodeScannerUtils";

    /**
     * 从ImageProxy中识别二维码
     * @param image ImageProxy对象
     * @return 识别结果，如果失败返回null
     */
    public static String scanQRCodeFromImageProxy(@NonNull ImageProxy image) {
        try {
            // 将ImageProxy转换为字节数组
            byte[] data = imageProxyToByteArray(image);
            if (data == null) {
                return null;
            }

            // 创建PlanarYUVLuminanceSource
            PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                    data, image.getWidth(), image.getHeight(), 0, 0,
                    image.getWidth(), image.getHeight(), false);

            // 创建BinaryBitmap
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 设置解码提示
            Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

            // 解码
            MultiFormatReader reader = new MultiFormatReader();
            reader.setHints(hints);
            Result result = reader.decode(bitmap);

            return result != null ? result.getText() : null;
        } catch (Exception e) {
            Log.d(TAG, "QR code scan failed: " + e.getMessage());
            return null;
        }
    }

    /**
     * 从图片URI中识别二维码
     * @param context 上下文
     * @param imageUri 图片URI
     * @return 识别结果，如果失败返回null
     */
    public static String scanQRCodeFromImageUri(Context context, Uri imageUri) {
        try {
            // 从URI加载Bitmap
            InputStream inputStream = context.getContentResolver().openInputStream(imageUri);
            if (inputStream == null) {
                return null;
            }

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            inputStream.close();

            if (bitmap == null) {
                return null;
            }

            // 转换为字节数组
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] pixels = new int[width * height];
            bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

            // 转换为灰度图
            byte[] luminance = new byte[width * height];
            for (int i = 0; i < pixels.length; i++) {
                int pixel = pixels[i];
                int r = (pixel >> 16) & 0xff;
                int g = (pixel >> 8) & 0xff;
                int b = pixel & 0xff;
                luminance[i] = (byte) ((r + g + b) / 3);
            }

            // 创建PlanarYUVLuminanceSource
            PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                    luminance, width, height, 0, 0, width, height, false);

            // 创建BinaryBitmap
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 设置解码提示
            Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

            // 解码
            MultiFormatReader reader = new MultiFormatReader();
            reader.setHints(hints);
            Result result = reader.decode(binaryBitmap);

            return result != null ? result.getText() : null;
        } catch (Exception e) {
            Log.e(TAG, "QR code scan from image failed", e);
            return null;
        }
    }

    /**
     * 从Bitmap中识别二维码
     * @param bitmap Bitmap对象
     * @return 识别结果，如果失败返回null
     */
    public static String scanQRCodeFromBitmap(Bitmap bitmap) {
        try {
            if (bitmap == null) {
                return null;
            }

            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] pixels = new int[width * height];
            bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

            // 转换为灰度图
            byte[] luminance = new byte[width * height];
            for (int i = 0; i < pixels.length; i++) {
                int pixel = pixels[i];
                int r = (pixel >> 16) & 0xff;
                int g = (pixel >> 8) & 0xff;
                int b = pixel & 0xff;
                luminance[i] = (byte) ((r + g + b) / 3);
            }

            // 创建PlanarYUVLuminanceSource
            PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                    luminance, width, height, 0, 0, width, height, false);

            // 创建BinaryBitmap
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 设置解码提示
            Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

            // 解码
            MultiFormatReader reader = new MultiFormatReader();
            reader.setHints(hints);
            Result result = reader.decode(binaryBitmap);

            return result != null ? result.getText() : null;
        } catch (Exception e) {
            Log.e(TAG, "QR code scan from bitmap failed", e);
            return null;
        }
    }

    /**
     * 将ImageProxy转换为字节数组
     * @param image ImageProxy对象
     * @return 字节数组
     */
    private static byte[] imageProxyToByteArray(@NonNull ImageProxy image) {
        if (image.getFormat() != ImageFormat.YUV_420_888) {
            Log.w(TAG, "Unsupported image format: " + image.getFormat());
            return null;
        }

        try {
            // 获取Y平面数据
            ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
            byte[] yData = new byte[yBuffer.remaining()];
            yBuffer.get(yData);

            return yData;
        } catch (Exception e) {
            Log.e(TAG, "Convert ImageProxy to byte array failed", e);
            return null;
        }
    }

    /**
     * 检查字符串是否为有效的URL
     * @param text 待检查的字符串
     * @return 是否为有效URL
     */
    public static boolean isValidUrl(String text) {
        if (text == null || text.trim().isEmpty()) {
            return false;
        }
        
        return text.startsWith("http://") || text.startsWith("https://") || 
               text.startsWith("ftp://") || text.startsWith("file://");
    }

    /**
     * 检查字符串是否为有效的邀请码
     * @param text 待检查的字符串
     * @return 是否为有效邀请码
     */
    public static boolean isValidInviteCode(String text) {
        if (text == null || text.trim().isEmpty()) {
            return false;
        }
        
        // 检查是否包含邀请码参数
        return text.contains("invite_code=") || text.contains("inviteCode=");
    }

    /**
     * 从URL中提取邀请码
     * @param url URL字符串
     * @return 邀请码，如果没有找到返回null
     */
    public static String extractInviteCode(String url) {
        if (url == null || url.trim().isEmpty()) {
            return null;
        }
        
        try {
            // 简单的参数提取逻辑
            if (url.contains("invite_code=")) {
                String[] parts = url.split("invite_code=");
                if (parts.length > 1) {
                    String codePart = parts[1];
                    // 如果后面还有其他参数，只取第一个参数
                    if (codePart.contains("&")) {
                        codePart = codePart.split("&")[0];
                    }
                    return codePart;
                }
            } else if (url.contains("inviteCode=")) {
                String[] parts = url.split("inviteCode=");
                if (parts.length > 1) {
                    String codePart = parts[1];
                    if (codePart.contains("&")) {
                        codePart = codePart.split("&")[0];
                    }
                    return codePart;
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Extract invite code failed", e);
        }
        
        return null;
    }
} 